/*
	Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/


#include "Text.h"
#include "../base/GameWorld.h"
#include "../base/Debuger.h"
#include "../render/TextCommand.h"
#include "Font.h"
#include "../base/Size.h"
#include "../base/Rect.h"
#include "../utility/utility.h"

namespace SkyEngine2d
{
	Text::Text(const std::wstring & text)
		:m_text(text)
	{
		m_cmd = std::make_unique<TextCommand>();
		setColor(Color4f::Black);
		updateLayout();
	}
	
	Text::~Text()
	{
	
	}
	
	void Text::setFont(const Font & font)
	{
		if (m_font == font)
		{
			return;
		}
		m_font = font;
		updateLayout();
	}
	
	Font & Text::getFont()
	{
		return m_font;
	}
	
	void Text::setColor(const Color4f& color)
	{
		if (m_color == color)
		{
			return;
		}
	
		m_color = color;
		m_cmd->setColor(color);
	}
	
	void Text::setDrawRect(const Rect & draw_rect)
	{
		if (m_drawRect == draw_rect)
		{
			return;
		}
	
		m_drawRect = draw_rect;
		m_cmd->setOriginalPoint(convertToRenderCoordinateVector2(Vector2(draw_rect.getLeft(), draw_rect.getTop())));
		m_textLayout->SetMaxWidth(draw_rect.getWidth());
		m_textLayout->SetMaxHeight(draw_rect.getHeight());
	}
	
	
	void Text::draw(IRender * render, const Matrix4X4 & transform /*= Matrix4X4::IdentityMat*/)
	{
	
		int size = m_text.size();
		if (m_text.size() <= 0)
		{
			return;
		}
		
		m_cmd->setTransform(transform);
	
		render->addRenderCommand(m_cmd.get());
	}
	
	
	void Text::setText(const std::wstring &text)
	{
		m_text = text;
		updateLayout();
	}
	
	/*Size Text::getTextPixelSize()
	{
		DWRITE_TEXT_METRICS m;
		m_textLayout->GetMetrics(&m);
	
		auto dpi = GameWorld::getInstance()->getD3dInterface()->getDpi();
	
		return Size(
			dpi.x / 160 * m.widthIncludingTrailingWhitespace
			, dpi.y / 160 * m.height);
	}
	*/
	
	Microsoft::WRL::ComPtr<IDWriteFactory> Text::getWriteFactory()
	{
		if (s_dwFactory==nullptr)
		{
			DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory),
				reinterpret_cast<IUnknown**>(s_dwFactory.GetAddressOf()));
		}
		return s_dwFactory;
	}
	
	void Text::updateLayout()
	{
		Text::getWriteFactory()->CreateTextLayout(
				m_text.c_str(),
				m_text.size(),
				m_font.getFormt().Get(),
				m_drawRect.getWidth(),
				m_drawRect.getHeight(),
				m_textLayout.ReleaseAndGetAddressOf()
		);
		m_cmd->setTextLayout(m_textLayout);
	}
	
	Microsoft::WRL::ComPtr<IDWriteFactory> Text::s_dwFactory=nullptr;
	
}
